<!doctype html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>防抖</title>
    <style>
        .box{
            width: 200px;
            height: 200px;
            background-color:skyblue;
        }
    </style>
</head>
<body>
    <div class="box"></div>
    <script>
        var el = document.getElementsByClassName("box")[0];
        /*防抖是初次触发时，不会被延迟。  防抖的使用场景比如 下拉刷新*/

        function fn(){
            console.log(1);
        }

        el.onmouseover = debounce(fn,1000,true);

        function debounce(fn,time,trggleNow){
            var t = null,
                res;

            var debounced = function(){
                var _this = this,   //保存this指向，当前这个函数的调用者，也就是 移入事件的本身 el
                    args = arguments;

                if(t){
                    clearTimeout(t); //每次执行，一开始就清除定时器；设置过定时器是，触发
                }

                if(trggleNow){  //判断是否一开始就执行
                    var exec = !t;    //time时间内未执行，t为null，exec是true


                    t = setTimeout(function(){   //相当于进来，就把门关上了。过一段时间，自动把门打开，让下面if可以在进行
                        // 每次进来t都会重新设置一遍，重新计时
                        t = null;  //clear定时器 和 t设置为bull 是两码事
                    },time);

                    if(exec){
                        res = fn.apply(_this,args);  // fn函数直接执行，fn this执行了当前事件
                    }
                }else{
                    // 每次进来t都会重新设置一遍，重新计时，最后只执行一遍
                    t = setTimeout(function(){
                        res = fn.apply(_this,args);
                    },time);
                }

                return res;   //如果需要返回值
            };

            debounced.remove = function(){  //关闭防抖,清除定时器，清除的是trggleNow = false情况下的定时器
                clearTimeout(t);
                t = null;
            };

            return debounced;
        }

    </script>
</body>
</html>
